package cn.dinkevin.xui.widget.image.fresco;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.ViewGroup;

import com.facebook.common.logging.FLog;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.image.QualityInfo;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import cn.dinkevin.xui.R;
import cn.dinkevin.xui.util.StringUtil;

/**
 * 异步加载图片控件
 * Created by chengpengfei on 2017/4/12.
 * Copyright ©2017 juziwl, All Rights Reserved.
 */

public class FrescoImageView extends SimpleDraweeView implements ControllerListener<ImageInfo>{

    private int rectangleLength;                    // 控件显示的最大正方形区域
    private boolean resizeToRectangle;              // 是否调整图片显示到最大长度的正方形区域内
    private String placeHolderImageUrl;                 // 点位图片资源

    public FrescoImageView(Context context) {
        super(context);
        initial(context,null);
    }

    public FrescoImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initial(context,attrs);
    }

    /**
     * 初始化
     * @param context
     * @param attrs
     */
    private void initial(Context context,AttributeSet attrs){

        if(attrs != null){
            TypedArray array = context.obtainStyledAttributes(
                    attrs,
                    R.styleable.XUIAsyncImageView);
            rectangleLength = array.getDimensionPixelSize(R.styleable.XUIAsyncImageView_rectangleLength,0);
            resizeToRectangle = array.getBoolean(R.styleable.XUIAsyncImageView_resizeToRectangle,false);
            placeHolderImageUrl = array.getString(R.styleable.XUIAsyncImageView_placeholderImage);
        }
    }

    /**
     * Called after the fetch of the final image failed.
     *
     * @param id        controller id
     * @param throwable failure cause
     */
    @Override
    public void onFailure(String id, Throwable throwable) {

    }

    /**
     * Called before the image request is submitted.
     * <p> IMPORTANT: It is not safe to reuse the controller from within this callback!
     *
     * @param id            controller id
     * @param callerContext caller context
     */
    @Override
    public void onSubmit(String id, Object callerContext) {

    }

    /**
     * Called after the final image has been set.
     *
     * @param id         controller id
     * @param imageInfo  image info
     * @param animatable
     */
    @Override
    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {

        // 根据 Image 信息来决定控件显示宽高
        if (imageInfo == null) {
            return;
        }

        QualityInfo qualityInfo = imageInfo.getQualityInfo();
        FLog.d("Final image received! " +
                        "Size %d x %d",
                "Quality level %d, good enough: %s, full quality: %s",
                imageInfo.getWidth(),
                imageInfo.getHeight(),
                qualityInfo.getQuality(),
                qualityInfo.isOfGoodEnoughQuality(),
                qualityInfo.isOfFullQuality());

        // 自动调整控件宽高
        if(rectangleLength > 0){

            ViewGroup.LayoutParams params = getLayoutParams();
            int width,height;
            if(resizeToRectangle){
                width = height = rectangleLength;
            }
            else
            {
                int imageWidth = imageInfo.getWidth();
                int imageHeight = imageInfo.getHeight();
                System.out.println("w:"+imageWidth+" h:"+imageHeight);

                float hh = imageHeight > rectangleLength ? rectangleLength : imageHeight;     //  高度最大值为
                float ww = imageWidth > rectangleLength ? rectangleLength : imageWidth;         //  宽度最大值为

                // 最长宽度或高度
                float be = 1.0f;

                if (imageWidth > imageHeight && imageWidth > ww) {
                    be = imageWidth / ww;
                } else if (imageWidth < imageHeight && imageHeight > hh) {
                    be = imageHeight / hh;
                }

                if (be <= 0) {
                    be = 1.0f;
                }

                width = (int)(imageWidth / be);
                height = (int)(imageHeight / be);

                if(width > rectangleLength){
                    width = rectangleLength;
                    height = rectangleLength;
                }
            }
            params.width = width;
            params.height = height;
            setLayoutParams(params);
        }
    }

    /**
     * Called after any intermediate image has been set.
     *
     * @param id        controller id
     * @param imageInfo image info
     */
    @Override
    public void onIntermediateImageSet(String id, ImageInfo imageInfo) {}

    /**
     * Called after the fetch of the intermediate image failed.
     *
     * @param id        controller id
     * @param throwable failure cause
     */
    @Override
    public void onIntermediateImageFailed(String id, Throwable throwable) {}

    /**
     * Called after the controller released the fetched image.
     * <p> IMPORTANT: It is not safe to reuse the controller from within this callback!
     *
     * @param id controller id
     */
    @Override
    public void onRelease(String id) {}

    /**
     * 不使用设置的placeHolder
     */
    public void disablePlaceholder(){
        this.setDrawingCacheEnabled(true);
        this.buildDrawingCache();
        Bitmap bitmap = this.getDrawingCache();
        if (bitmap != null){
            Bitmap b = Bitmap.createBitmap(bitmap);
            if(b != null){
                Drawable drawable = new BitmapDrawable(b);
                if (drawable != null) {
                    this.getHierarchy().setPlaceholderImage(drawable);
                }
            }
        }
        this.setDrawingCacheEnabled(false);
    }

    /**
     * 获取当前显示缓存图片
     * @return
     */
    public Drawable getCurrentCacheBitmap(){
        this.setDrawingCacheEnabled(true);
        this.buildDrawingCache();
        Drawable drawable = null;
        Bitmap bitmap = this.getDrawingCache();
        if (bitmap != null){
            Bitmap b = Bitmap.createBitmap(bitmap);
            if(b != null){
                drawable = new BitmapDrawable(b);
            }
        }
        this.setDrawingCacheEnabled(false);
        return drawable;
    }

    /**
     * 设置异步图片载路径
     * @param url
     */
    public void setAsyncLoadingUrl(String url){

        String imageUrl = url;

        // 如果为空则加载默认的图片
        if(StringUtil.isEmpty(imageUrl)) {
            imageUrl = placeHolderImageUrl;
        }

        if(StringUtil.isEmpty(imageUrl)) return;

        // 初始化图片请求
        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageUrl))
                .setAutoRotateEnabled(true)                 // 打开自动旋转
                .setProgressiveRenderingEnabled(true)       // 打开渐进式
                .build();

        // 绑定图片加载进度监听
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setImageRequest(imageRequest)
                .setControllerListener(this)
                .setOldController(getController())
                .setAutoPlayAnimations(true)
                .build();

        setController(controller);
    }
}
